<?php
namespace restphp\common\exploitation\filter;
use restphp\common\exploitation\exception\ExploitationException;
use restphp\common\exploitation\upload\constant\RestUploadConstant;
use restphp\core\RestCallAnyWhere;
use restphp\core\RestCallAnyWhereConstant;
use restphp\http\RestHttpRequest;
use restphp\http\RestHttpStatus;
use restphp\utils\RestStringUtils;

/**
 * Created by zj.
 * User: zj
 * Date: 2019/8/28 0028
 * Time: 下午 3:45
 */
class UploadFilter {
    /**
     * @param $strUri
     * @throws \restphp\exception\RestException.
     */
    public static function filter($strUri) {
        //总配置检查.
        if (!isset($GLOBALS[RestUploadConstant::UPLOAD_CONFIG_NAME])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR);
        }

        //一级配置检查.
        $arrConfig = $GLOBALS[RestUploadConstant::UPLOAD_CONFIG_NAME];
        if (!isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SAVE_ROOT]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_VISIT_URI])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR);
        }

        $strStartUri = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_VISIT_URI];

        $strMethod = RestHttpRequest::getServer("REQUEST_METHOD");
        if (substr($strUri,0, strlen($strStartUri . "/")) == $strStartUri . "/" && "GET" == strtoupper($strMethod)) {
            $arrRightConfig = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT];
            //权限检查
            $strFile = substr($strUri, strlen($strStartUri . "/"));
            $arrUriCols = explode("/", $strFile);
            if (!isset($arrUriCols[0]) || !isset($arrUriCols[1])) {
                throw new ExploitationException(RestUploadConstant::UPLOAD_VISIT_ERROR_RIGHT_CODE_EMPTY, RestHttpStatus::Unauthorized);
            }
            $rightCode = $arrUriCols[0];
            if (RestStringUtils::isBlank($rightCode) || !isset($arrRightConfig[$rightCode])) {
                throw new ExploitationException(RestUploadConstant::UPLOAD_VISIT_ERROR_RIGHT_CODE_EMPTY, RestHttpStatus::Unauthorized);
            }

            //业务权限校验
            $rightCallConfig = $arrRightConfig[$rightCode];
            if (isset($rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_VISIT])) {
                $bizCall = $rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_VISIT];
                $bizCall[RestCallAnyWhere::PARAMETER_NAME_PARAMETERS] = array(
                    'rightCode' => $rightCode,
                    'url' => $strUri
                );
                RestCallAnyWhere::call($bizCall);
            }

            //读取文件
            $strRoot = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SAVE_ROOT];
            $strFileRealPath = $strRoot . DIRECTORY_SEPARATOR . str_replace("/", DIRECTORY_SEPARATOR, $strFile);
            if (!file_exists($strFileRealPath)) {
                throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_VISIT, RestHttpStatus::Not_Found);
            }

            //格式化输出头
            self::_echoHeader($strFileRealPath);

            //输出文件
            ob_clean();
            echo file_get_contents($strFileRealPath);

            die();
        }
    }

    private static $_mediaMap = array(
        255216 => 'image/jpeg',
        6677 => 'application/x-bmp',
        7173 => 'image/gif',
        13780 => 'image/png',
        'other' => 'application/octet-stream'
    );

    private static function _echoHeader($strFile) {
        $fp = fopen($strFile, "rb");
        $bin = fread($fp, 2); //只读2字节
        fclose($fp);
        // unpack() 函数从二进制字符串对数据进行解包
        $strInfo  = unpack("C2chars", $bin);
        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);

        $media = isset(self::$_mediaMap[$typeCode]) ? self::$_mediaMap[$typeCode] : self::$_mediaMap['other'];
        header('Content-Type: ' . $media . '; charset=utf-8');
    }
}